package org.jvnc.vnc;

/**
* <br><br><center><table border="1" width="80%"><hr>
* <p>
* Copyright (C) 2006-2007 by Deon Wu
* <p>
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.0
* of the License, or (at your option) any later version.
* <p>
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU Lesser General Public License</a>
* for more details.
* <p>
* You should have received a copy of the <a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">
* GNU Lesser General Public License</a> along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* <hr></table></center>
* **/

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.KeyboardFocusManager;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.Collection;

import org.jvnc.logging.VLog;

public class VncScreen extends Canvas implements KeyListener,MouseListener, MouseMotionListener, FocusListener{
	private static final VLog log = VLog.getLog(VncScreen.class);
	
	private Image bufferScreen = null;
	//private
	/**
	 * 显示屏幕的指定区域 
	 */
	private int clipX;
	private int clipY;
	private int clipWidth;
	private int clipHeight;
	
	private int screenWidth = 0;
	private int screenHeight = 0;
	private boolean havePreferSize = false;
	
	private VncInputListener inputListener = null;
	private KeyboardFocusManager orginalKM = null; 
	private KeyboardFocusManager vncKM = null;
	
	//private Image buffer = null;
	
	public VncScreen(){
		clipX = 0;
		clipY = 0;
		clipWidth = 0;
		clipHeight = 0;
		
		this.addKeyListener(this);
		this.addMouseListener(this);
		this.addMouseMotionListener(this);
		this.addComponentListener(new ComponentAdapter(){
			public void componentResized(ComponentEvent e){
				if(!havePreferSize){
					screenWidth = e.getComponent().getWidth();
					screenHeight = e.getComponent().getHeight();
				}
			} 
		});
		
		this.addFocusListener(this);
		vncKM = new KFM();
		
		//buffer = this.
	}
	
	public void addVncInputListener(VncInputListener l){
		inputListener = l;
	}
	
	public void paint(Graphics g){
		if(bufferScreen != null){
			//log.debug("screenWidth:" + screenWidth + " screenHeight:" + screenHeight);
			//log.debug("clipX:" + clipX + " clipY:" + clipY + "clipWidth:" + clipWidth + " clipHeight:" + clipHeight);
			//g.drawImage(bufferScreen, 0,0, null);
//			Image buffer = this.createImage(screenWidth, screenHeight);
//			Graphics g1 = buffer.getGraphics();
			g.drawImage(bufferScreen, 0,0,screenWidth,screenHeight,
					clipX, clipY, clipWidth + clipX, clipHeight + clipY,
					null);
//			g1.dispose();
//			g.drawImage(buffer,0,0,this);
		} else{
			g.drawString("Not found screen buffer!", 100, 100);
		}
		
	}
	
	public void setPreferredSize(Dimension dim){
		super.setPreferredSize(dim);
		havePreferSize = true;
		screenHeight = (int)dim.getHeight();
		screenWidth = (int)dim.getWidth();
	}
	
	public void setClip(int x, int y, int width, int height){
		this.clipX = x;
		this.clipY = y;
		this.clipWidth = width;
		this.clipHeight = height;
	}
	
	public void setBufferScreen(Image img){
		if(img != null){
			this.bufferScreen = img;
			if(clipWidth == 0){
				clipWidth = img.getWidth(null);  
			}
			if(clipHeight == 0){
				clipHeight = img.getHeight(null);  
			}
		}
	}

	public void keyPressed(KeyEvent event) {
		if(inputListener != null){
			inputListener.keyPressed(event);
		}		
	}

	public void keyReleased(KeyEvent event) {
		if(inputListener != null){
			inputListener.keyReleased(event);
		}		
		
	}

	public void keyTyped(KeyEvent event) {
		if(inputListener != null){
			inputListener.keyTyped(event);
		}	
	}

	public void mouseClicked(MouseEvent event) {
		translatePoint(event);
		if(inputListener != null){
			inputListener.mouseClicked(translatePoint(event));
		}			
	}

	public void mouseEntered(MouseEvent event) {
		if(inputListener != null){
			if(inputListener.isActive()){
				this.requestFocus();
				orginalKM = KeyboardFocusManager.getCurrentKeyboardFocusManager();
				KeyboardFocusManager.setCurrentKeyboardFocusManager(vncKM);
			}
			inputListener.mouseEntered(translatePoint(event));
		}		
	}

	public void mouseExited(MouseEvent event) {
		KeyboardFocusManager.setCurrentKeyboardFocusManager(orginalKM);
		if(inputListener != null){
			inputListener.mouseExited(translatePoint(event));
		}		
	}

	public void mousePressed(MouseEvent event) {
		if(inputListener != null){
			inputListener.mousePressed(translatePoint(event));
		}		
	}

	public void mouseReleased(MouseEvent event) {
		if(inputListener != null){
			inputListener.mouseReleased(translatePoint(event));
		}		
	}

	public void mouseDragged(MouseEvent event) {
		if(inputListener != null){
			inputListener.mouseDragged(translatePoint(event));
		}
	}

	public void mouseMoved(MouseEvent event) {
		if(inputListener != null){
			inputListener.mouseMoved(translatePoint(event));
		}
	}
	
	/**
	 * 将显示屏暮的事件坐标转换到缓冲帧上对应的坐标。
	 * @param event
	 * @return
	 */
	public MouseEvent translatePoint(MouseEvent event){
		int x1 = (clipWidth / screenWidth - 1) * event.getX() + clipX;
		int y1 = (clipHeight / screenHeight - 1) * event.getY() + clipY;
		
		//log.debug("translatePoint x=" + event.getX() + " to X=" + x1);
		//log.debug("translatePoint y=" + event.getY() + " to Y=" + y1);
		event.translatePoint(x1,y1);
		//log.debug("after translatePoint X=" + event.getX() + " to Y=" + event.getY());
		
		return event;
	}

	public void focusGained(FocusEvent arg0) {
	}

	public void focusLost(FocusEvent arg0) {
	} 
	
	class KFM extends java.awt.DefaultKeyboardFocusManager
	{
		KFM(){
			super();
			Collection<java.awt.KeyEventDispatcher> kds = getKeyEventDispatchers();
			if(kds != null)
			for(java.awt.KeyEventDispatcher kd : kds){
				this.removeKeyEventDispatcher(kd);
			} 
		}
		
		public boolean dispatchKeyEvent(KeyEvent e){
			if(inputListener != null &&
			   inputListener.isActive() &&
			   e.getID() == KeyEvent.KEY_RELEASED){
				inputListener.processLocalKeyEvent(e);
			}
			e.consume();
			return false;
		} 
	}	
}
